const ffmpeg = require('ffmpeg-static');
const { createWorker } = require('tesseract.js');
const { exec } = require('child_process');
const fs = require('fs');
const path = require('path');
const config = require('../config/config');
const sharp = require('sharp');

class TextExtractor {
    async preprocessImage(imagePath) {
        try {
            await sharp(imagePath)
                .resize(1280, 720, {
                    fit: 'inside',
                    withoutEnlargement: false
                })
                .sharpen()
                .contrast(1.2)
                .toFile(imagePath + '_processed.jpg');

            // 替换原文件
            fs.renameSync(imagePath + '_processed.jpg', imagePath);
        } catch (error) {
            console.error('图像预处理失败:', error.message);
        }
    }

    async extractText(videoPath) {
        try {
            const framesDir = path.join(config.TEMP_DIR, 'frames');
            if (!fs.existsSync(framesDir)) {
                fs.mkdirSync(framesDir, { recursive: true });
            }

            // 提取视频帧
            await this.extractFrames(videoPath, framesDir);

            // OCR识别
            const texts = await this.performOCR(framesDir);

            // 清理临时文件
            fs.rmSync(framesDir, { recursive: true, force: true });

            return Array.from(new Set(texts)).join('\n');
        } catch (error) {
            console.error('Error extracting text:', error.message);
            return null;
        }
    }

    async extractFrames(videoPath, outputDir) {
        return new Promise((resolve, reject) => {
            const command = `${ffmpeg} -i "${videoPath}" -vf fps=1 "${path.join(outputDir, 'frame-%d.jpg')}"`;
            
            exec(command, (error) => {
                if (error) {
                    reject(error);
                    return;
                }
                resolve();
            });
        });
    }

    async performOCR(framesDir) {
        const worker = await createWorker('chi_sim');
        const texts = [];

        const frames = fs.readdirSync(framesDir)
            .filter(file => file.endsWith('.jpg'))
            .map(file => path.join(framesDir, file));
        
        // 在 OCR 之前添加预处理
        for (const frame of frames) {
            await this.preprocessImage(frame);
            const { data: { text } } = await worker.recognize(frame);
            if (text.trim()) {
                texts.push(text.trim());
            }
        }
        
        await worker.terminate();
        return texts;
    }
}

module.exports = TextExtractor;